﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace XMK.Utils
{
    public static class TypeHelper
    {
        /// <summary>
        /// 根据基本类型，返回系统类型
        /// </summary>
        /// <param name="baseType">基本类型，如：int，string</param>
        /// <returns>System.String、System.Boolean等系统格式的类型</returns>
        public static string GetBaseDataType(string baseType)
        {
            string systemType = string.Empty;
            switch (baseType.ToLower())
            {
                case "ushort":
                    systemType = "System.UInt16";
                    break;
                case "short":
                    systemType = "System.Int16";
                    break;
                case "int":
                    systemType = "System.Int32";
                    break;
                case "ulong":
                    systemType = "System.UInt64";
                    break;
                case "long":
                    systemType = "System.Int64";
                    break;
                case "float":
                    systemType = "System.Single";
                    break;
                case "double":
                    systemType = "System.Double";
                    break;
                case "decimal":
                    systemType = "System.Decimal";
                    break;
                case "string":
                    systemType = "System.String";
                    break;
                case "bool":
                    systemType = "System.Boolean";
                    break;
                case "byte":
                    systemType = "System.Byte";
                    break;
                case "char":
                    systemType = "System.Char";
                    break;
                case "datetime":
                    systemType = "System.DateTime";
                    break;

            }

            return systemType;
        }

        /// <summary>
        /// 将数据库的表字段类型转换成.Net中的数据类型
        /// </summary>
        /// <param name="sqlServerType">数据库的表字段类型</param>
        /// <returns>.Net中的数据类型</returns>
        public static string GetCShapType(string sqlServerType)
        {
            switch (sqlServerType.ToLower())
            {
                case "bigint": return "int64";
                case "binary": return "byte[]";
                case "bit": return "bool";
                case "char": return "string";
                case "date": return "string";
                case "datetime": return "DateTime";
                case "datetime2": return "string";
                case "datetimeoffset": return "string";
                case "decimal": return "decimal";
                case "float": return "double";
                case "geography": return "byte[]";
                case "geometry": return "byte[]";
                case "hierarchyid": return "Byte[]";
                case "image": return "byte[]";
                case "int": return "int";
                case "money": return "decimal";
                case "nchar": return "string";
                case "ntext": return "string";
                case "numeric": return "decimal";
                case "nvarchar": return "string";
                case "real": return "single";
                case "smalldatetime": return "DateTime";
                case "smallint": return "int16";
                case "smallmoney": return "decimal";
                case "sql_variant": return "object";
                case "text": return "string";
                case "time": return "string";
                case "timestamp": return "byte[]";
                case "tinyint": return "byte";
                case "uniqueidentifier": return "Guid";
                case "varbinary": return "byte[]";
                case "varchar": return "string";
                case "xml": return "string";
                default: return "object";
            }
        }

        /// <summary>    
        /// 深拷贝对象
        /// </summary>    
        /// <typeparam name="T">The type of object being copied.</typeparam>    
        /// <param name="source">The object instance to copy.</param>    
        /// <returns>The copied object.</returns>    
        public static T Clone<T>(T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("对象必须能序列化", "source");
            }
            // Don't serialize a null object, simply return the default for that object      
            if (Object.ReferenceEquals(source, null))
            {
                return default(T);
            }
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }
    }
}
